﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace countlines
{
    class CodeLines
    {
        class Extension
        {
            public int m_Lines;
            public int m_Files;

            public Extension()
            {
                m_Lines = 0;
                m_Files = 0;
            }
        }

        public ConsoleFontColor mClrColor;
        private String mStartPath;

        private Hashtable htExt;

        public CodeLines(string[] types, ConsoleFontColor inClrColor)
        {
            htExt = new Hashtable();
            foreach (var t in types)
            {
                htExt.Add(t.ToLower(), new Extension());
            }
            mClrColor = inClrColor;
        }

        public void doCounting(String inStartPath)
        {
            mStartPath = ((inStartPath == "") ? Environment.CurrentDirectory : inStartPath);
            try
            {
                dfs(new DirectoryInfo(mStartPath));
            }
            catch (IOException ex)
            {
                mClrColor.TextColor((int)ConsoleFontColor.Foreground.Red + (int)ConsoleFontColor.Foreground.Intensity);
                Console.WriteLine("Exception:" + ex.Message);
                mClrColor.ResetColor();
            }
        }

        private int CountFileLines(String filename)
        {
            var objReader = new StreamReader(filename);
            String sLine = "";
            int Cnt = 0;
            while (sLine != null)
            {
                sLine = objReader.ReadLine();
                if (sLine != "")
                {
                    Cnt++;
                }
                
            }
            objReader.Close();
            return Cnt;
        }

        private void dfs(FileSystemInfo info)
        {
            if (!info.Exists)
            {
                return;
            }
            var dir = info as DirectoryInfo;
            if (dir == null)
            {
                return;
            }
            try
            {
                FileSystemInfo[] files = dir.GetFileSystemInfos();
                for (int i = 0; i < files.Length; i++)
                {
                    var file = files[i] as FileInfo;

                    if (file != null) // it is a file
                    {
                        String ext = Path.GetExtension(file.ToString());

                        if (htExt.Contains(ext.ToLower()))
                        {
                            int tmp = CountFileLines(file.Directory + "\\" + file);
                            Extension ex = (Extension)htExt[ext.ToLower()];
                            ex.m_Lines += tmp;
                            ex.m_Files++;
                            Console.WriteLine(tmp + " row(s)\t" + file.Directory + "\\" + file);
                        }
                    }
                    else
                    {
                        dfs(files[i]);
                    }
                }
            }
            catch (Exception ex)
            {
                mClrColor.TextColor((int)ConsoleFontColor.Foreground.Red + (int)ConsoleFontColor.Foreground.Intensity);
                Console.WriteLine("Exception: " + ex.Message);
                mClrColor.ResetColor();
                return;
            }
        }

        public void OutputResult()
        {
            int totalLines = 0;
            int totalFiles = 0;
            mClrColor.TextColor((int)ConsoleFontColor.Foreground.Green + (int)ConsoleFontColor.Foreground.Intensity);
            Console.WriteLine();
            foreach (DictionaryEntry v in htExt)
            {
                totalLines += ((Extension) v.Value).m_Lines;
                totalFiles += ((Extension) v.Value).m_Files;
                Console.WriteLine(((string)v.Key) + ": \t" + 
                    ((Extension)v.Value).m_Files.ToString() + " files, " +
                    ((Extension)v.Value).m_Lines.ToString() + " lines.");
            }
            Console.WriteLine("\nTotal Files: " + totalFiles + " piece(s).");
            Console.WriteLine("Total Lines: " + totalLines + " row(s).");
            Console.WriteLine("Command Completed Successfully.\n");
            mClrColor.ResetColor();
        }
    }
}
